package com.sky.service.admin.impl;


import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.RedisConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.admin.DishFlavorMapper;
import com.sky.mapper.admin.DishMapper;
import com.sky.pojo.Dish;
import com.sky.pojo.DishFlavor;
import com.sky.result.PageResult;
import com.sky.service.admin.DishService;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;


import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class DishServiceImpl implements DishService {

    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorMapper dishFlavorMapper;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 套餐id查询包含的菜品
     * @param setmealId
     * @return
     */
    @Override
    public List<DishItemVO> getDish(Long setmealId) {

        log.info("C端套餐id查询包含的菜品{}", setmealId);

        List<DishItemVO> dishItemVOList = dishMapper.getDish(setmealId);
        return dishItemVOList;
    }

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult get(DishPageQueryDTO dto) {
        //分页插件 动态sql
        PageHelper.startPage(dto.getPage(), dto.getPageSize());
        log.info("分页{}，总页{}", dto.getPage(), dto.getPageSize());

        Page<Dish> dishPage = dishMapper.get(dto);
        log.info("逻辑层返回的getTotal#{}，getResult#{}", dishPage.getTotal(), dishPage.getResult());
        return new PageResult(dishPage.getTotal(), dishPage.getResult());
    }


    /**
     * 新增菜品
     *
     * @param dto
     */
    @Override
    @Transactional

    public void add(DishDTO dto) {
        //本质：两张表dish 和DishFlavor
        dto.setStatus(StatusConstant.DISABLE);//设置菜品默认禁用

        Dish dish = new Dish();
        log.info("新增菜品拷贝之前的dto{}，dish{}", dto, dish);

        //1.调用方法 拷贝    新增的信息拷贝到 employee
        BeanUtils.copyProperties(dto, dish);

        log.info("拷贝之后dto{}，dish{}", dto, dish);

        //2.新增dish菜品
        dishMapper.addDish(dish);

        //1.1状态设置 为默认0-    在StatusConstant类中静态代码块
        dish.setStatus(StatusConstant.DISABLE);

        //3.获取DishFlavor口味的主键        口味表是菜品中的一个集合
        List<DishFlavor> flavors = dto.getFlavors();
        //用stringfeamework中的  判断集合中不为null
        if (!CollectionUtils.isEmpty(flavors)) {
            //遍历
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dish.getId());//设置菜品主键dish.id
            }
            log.info("口味主键{}", flavors);
            dishFlavorMapper.addDf(flavors);


        }


    }


    /**
     * 修改菜品
     * @param dto
     */
    @Override
    @Transactional //提交事务
    @CachePut(value = "update",key = "#dto")
    public void update(DishDTO dto) {
        log.info("删除菜品请求{}", dto);

        // 1. 更新 dish 表中的菜品信息
        Dish dish = new Dish();
        BeanUtils.copyProperties(dto, dish);
        dishMapper.updateDish(dish);

        // 2. 删除 dish_flavor 表中与当前菜品关联的所有口味
        dishFlavorMapper.deleteDfByDishId(dish.getId());  //这个需要删调吗？因为有注解了

        // 3. 插入新的口味数据
        List<DishFlavor> flavors = dto.getFlavors();
        if (!CollectionUtils.isEmpty(flavors)) {
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dish.getId()); // 设置菜品ID
            }
            dishFlavorMapper.addDf(flavors); // 批量插入口味
        }

        log.info("菜品修改成功，id: {}", dish.getId());
    }


    //删除菜品
    @Override
    @Transactional //事务
    @CacheEvict(value = "shanchu",key ="#ids")//从缓存中删除一条 或 多条数据
    public void delete(List<Long> ids) {
        //判断菜品是否启用
        Integer count = dishMapper.getStatus(ids);

        log.info("判断菜品是否启用connt={}", count);
        if (count > 0) {
            throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
        } else {
            //删除菜品
            dishMapper.deleteDish(ids);
            //删除口味
            dishFlavorMapper.deleteDf(ids);

        }
    }

    //查询菜品
    @Override
    public DishDTO getDishById(Long id) {

        // 查询菜品的基本信息  根据菜品分类id 返回所有的菜品
        Dish dish = dishMapper.getDishById(id);

        if (dish == null) {
            return null;
        }

        // 查询菜品的口味信息
        List<DishFlavor> flavors = dishFlavorMapper.getFlavorsByDishId(id);

        // 构建 DTO 对象
        DishDTO dto = new DishDTO();
        BeanUtils.copyProperties(dish, dto);  // 复制菜品信息到 DTO
        dto.setFlavors(flavors);  // 设置口味信息

        return dto;
    }

    /**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
     */
    @Override
    @CachePut(value = "Dish",key = "#categoryId")
    public List<Dish> getByIdDish(Long categoryId) {
        return dishMapper.getByIdDish(categoryId);
    }

    /**
     * 启动、禁用菜品
     *
     * @param status
     * @param id
     */
    @Override
    public void setStatus(Integer status, Integer id) {
        dishMapper.setStatus(status, id);
    }

    /**
     * 根据分类id查询菜品
     * 完成缓存中查询
     * @param categoryId
     * @return
     */
    @Override

    @CachePut(value ="DishVO",key = "#pO.id")//#.p0 （p0 值方法中的第一个参数，id第一个参数的id，也就是根据id属性作为key操作）  格式：#
    public List<DishVO> getDishCategoryId(Long categoryId) {
        //Key 一定要加业务前端
        String key = RedisConstant.CATEGORY_CACHE_PREFIX + categoryId;
        String dishJson = (String) redisTemplate.opsForValue().get(key);
        if (StringUtils.hasText(dishJson)) {
            log.info("从缓存查询，categoryId{}", categoryId);
            List<DishVO> dishVOList = JSONObject.parseArray(dishJson, DishVO.class);
            return dishVOList;
        }
        log.info("c端-根据分类id查询菜品{}", categoryId);
        List<DishVO> dishVOList = dishMapper.getDishCategoryId(categoryId);

        return dishVOList;
    }


    /**
     * 清理缓存数据
     */
    private void cleancache(String pattern) {//pattern 就是参数名字而已
        Set keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }

}










